(function() {
    Nokia.Tooltip = Nokia.Widget.extend({
        initialize: function(options) {
            var instance = this;

			var defaults = {
				description: ' - ',
				timeout: 3000,
				offset: [0, -15],
				roundedCorners: true,
				zIndex: false,
				direction: 'above center'
            };

            instance.options = jQuery.extend(defaults, options);

            instance.element = jQuery( instance.options.element );

            instance._super.apply(instance, [instance.options]);

            instance.registerData("tooltip");

            instance._create();
            instance._attachEvents();

			instance.registerVibrationOn([ 'click','show' ]);
			instance.fireCallback('create');
        },

		_attachEvents: function() {
			var instance = this;
			var options = instance.options
			var element = instance.element;
			var wrapper = element.parent();
			var Styles = instance.Styles;

			jQuery('body').click(function() {
				instance.hide();
			});
		},

		_applyDirectionStyle: function(direction){
			var instance = this;
			var wrapperContainer = instance.wrapperContainer;
			var wrapper = instance.wrapper;
			var Styles = instance.Styles;

			wrapper.removeClass( [Styles.nokiaTooltipLeft, Styles.nokiaTooltipRight].join(' ') );

			if ( /left/i.test( direction ) ) {
				wrapper.addClass( Styles.nokiaTooltipRight );
			}
			else if ( /right/i.test( direction ) ) {
				wrapper.addClass( Styles.nokiaTooltipLeft );
			}

			var pointerClass = Styles.tooltipBorder;
			var pointer = wrapper.find( '.' + pointerClass );

			if ( /bottom/i.test(direction) ) {
				pointer[0].className = [Styles.nokiaTooltipPointerUp, pointerClass].join(' ');
			}
			else {
				pointer[0].className = [Styles.nokiaTooltipPointerDown, pointerClass].join(' ');
			}

		},

		_create: function() {
			var instance = this;
			var options = instance.options;
			var element = instance.element;
			var Styles = instance.Styles;
			var width = options.width;
			var height = options.height;

			jQuery.each(element, function(i, el) {
				var wrapper = Nokia.dom.parseHTML('<div class="' + [Styles.nokiaTooltip, Styles.uiWidget, Styles.uiWidgetContent, Styles.uiStateActive].join(' ') + '"></div>');
				var description = Nokia.dom.parseHTML('<span>' + options.description + '</span>');
				var pointer = Nokia.dom.parseHTML('<div class="' + [Styles.nokiaTooltipPointerDown, Styles.tooltipBorder].join(' ') +'">');

				Nokia.dom.append(wrapper, description);
				Nokia.dom.append(wrapper, pointer);

				wrapper.click(function(event) {
					event.stopPropagation();
				});

				instance.wrapper = wrapper;

				var wrapperContainer = Nokia.dom.parseHTML('<div class="' + [Styles.nokiaTooltipWrapperConatainer].join(' ') + '"></div>');
				Nokia.dom.append(wrapperContainer, wrapper);

				instance.wrapperContainer = wrapperContainer;

				Nokia.dom.append(document.body, wrapperContainer);

				var action = function(event) {
					var zIndex;

					if ( options.zIndex === false ) {
						zIndex = (parseInt(Nokia.Tooltip.zIndex, 10) || 0) + 1;
						Nokia.Tooltip.zIndex = zIndex;
					}
					else {
						zIndex = options.zIndex;
					}

					wrapperContainer.css({
						zIndex: zIndex
					});

					instance.show(event, wrapperContainer);

					event.stopPropagation();
				};

				jQuery(el).bind('click.tooltip', action);
				Nokia.util.bindEnter(el, action);

				if ( !options.startVisible ) {
					wrapperContainer.hide();
				}

				if ( options.disabled ) {
					Nokia.util.addClass(el, Styles.stateDisabled);
				}

				if ( options.roundedCorners ) {
					Nokia.util.applyRoundedCorners(wrapper, Styles.nokiaStateActive);
				}

				Nokia.util.disableSelection(wrapper);
			});

		},

		_position: function(tooltip, options) {
			var instance = this;
			var Styles = instance.Styles;

			options = jQuery.extend({
				around: '.tooltip',
				direction: 'above center',
				forceDirection: false,
				offset: [0, 0]
			}, options);

			var leftOffset = 0,
				topOffset = 0,
				height = tooltip.outerHeight(),
				width = tooltip.outerWidth();

			if ( jQuery(options.around).length && jQuery(options.around)[0].nodeName ) {

				var element = jQuery(options.around),
					offset = element.offset(),
					relHeight = element.outerHeight(),
					relWidth = element[0].offsetWidth,
					wWidth = window.innerWidth,
					wHeight = window.innerHeight,
					left = offset.left - width + options.offset[0],
					right = offset.left + relWidth + options.offset[0],
					center = offset.left - (width / 2)  + (relWidth / 2) + options.offset[0],
					above = offset.top - height + options.offset[1],
					bottom = offset.top + relHeight + options.offset[1] + 20,
					direction
				;

				if (( /left/i ).test( options.direction )) {
					leftOffset = left;
					direction = 'left';

					if (left < 0) {
						leftOffset = right;
						direction = 'right';
					}

					if (leftOffset + width > wWidth) {
						direction = 'center';
						leftOffset = center;
					}

				}
				else if (( /right/i ).test( options.direction )) {
					leftOffset = right;
					direction = 'right';

					if ( leftOffset + width > wWidth ) {
						direction = 'center';
						leftOffset = center;
					}

				}
				else {
					direction = 'center';
					leftOffset = center;

					if ( leftOffset < 0 ) {
						leftOffset = right;
						direction = 'right';
					}
				}

				if (( /bottom/i ).test( options.direction )) {
					topOffset = bottom;
					direction += ' bottom';
				}
				else {
					var parentScrollTop = jQuery(window).scrollTop();

					if ( above < parentScrollTop ) {
						topOffset = bottom;
						direction += ' bottom';
					}
					else {
						topOffset = above;
						direction += ' above';
					}
				}

				instance._applyDirectionStyle(direction);

				tooltip.css({
					left: leftOffset,
					top: topOffset
				});
			}

		},

		show: function(event, tooltip) {
			var instance = this;
			var options = instance.options;
			var element = instance.element;

			instance._position(tooltip, {
				item: element,
				around: element,
				direction: options.direction,
				offset: options.offset
			});

			tooltip.show();

			instance.fireCallback('show', event);

			if (!instance.interval) {
				instance.interval = setInterval(function() {
					instance.show(event, tooltip);
				}, 500);
			}

			if (!instance.timeout) {
				instance.timeout = setTimeout(
					function() {
						instance.hide();
					},
					options.timeout
				);
			}

		},

		hide: function() {
			var instance = this;
			var Styles = instance.Styles;

			clearInterval(instance.interval);
			instance.interval = false;

			clearTimeout(instance.timeout);
			instance.timeout = false;

			instance.wrapperContainer.hide();
		},

		Styles: {
			nokiaTooltip: 'nokia-tooltip-element',
			nokiaTooltipRight: 'nokia-tooltip-right',
			nokiaTooltipLeft: 'nokia-tooltip-left',
			nokiaTooltipPointer: 'nokia-tooltip-pointer',
			nokiaTooltipPointerDown: 'nokia-tooltip-pointer-down',
			nokiaTooltipPointerUp: 'nokia-tooltip-pointer-up',
			nokiaTooltipPointerDownInner: 'nokia-tooltip-pointer-down-inner',
			nokiaTooltipWrapperConatainer: 'nokia-tooltip',
			nokiaStateActive: 'nokia-border-state-active',
			uiWidget: 'ui-widget',
			uiWidgetContent: 'ui-widget-content',
			uiStateActive: 'ui-state-active',
			stateDisabled: 'nokia-tooltip-disabled',
			tooltipBorder: 'nokia-tooltip-border'
		}
    });
})();